<template>
  <div class="table-com" :class="{ summary }">
    <el-table
      v-loading="table.loading"
      ref="Table"
      :data="table.data"
      :show-summary="summary"
      :summary-method="summaryMethod"
      :height="height"
      :span-method="spanMethod || (() => {})"
      :render-header="renderHeader || (() => {})"
      @selection-change="selectionChange"
      @row-dblclick="dblclick"
      @row-click="handleRowClick"
      @cell-mouse-enter="cellHoverIn"
    >
      <!--    
                直接使用 type="selection" 偶现checkbox无效，
                但先加载checkbox后再去除 后续checkbox正常渲染
                获取更换更高版本后不会出现？
            -->
      <el-table-column v-if="!renderDone" width="55">
        <template #header><el-checkbox /></template>
      </el-table-column>
      <!-- selection -->
      <el-table-column v-if="selection" type="selection" width="60" />

      <!-- index -->
      <el-table-column v-if="index" type="index" width="60" />

      <!-- 其他列表 -->
      <slot></slot>
    </el-table>

        <pagination
            v-if="
                pagination && table.data.length && table.page.pageNum && !list
            "
            :total="table.total"
            :page.sync="table.page.pageNum"
            :limit.sync="table.page.pageSize"
            @pagination="getData(table.search)"
        />

    <slot name="dom"></slot>
  </div>
</template>
                
                

<script>
// let timer;
export default {
    props: {
        // 请求的接口地址
        api: Function,
        // 列表的默认参数,例同接口不同type
        params: Object,
        // 列表高度
        height: {
            type: String,
            default: "50vh",
        },
        // 是否开启表头的选择框
        selection: {
            type: Boolean,
            default: false,
        },
        index: {
            type: Boolean,
            default: false,
        },
        // 这两个属性用于表格表单时使用
        list: Array, // 不走接口直接加载表格时的数据
        submit: Boolean, // 是否处于提交状态（loading）
        // 是否显示合计
        summary: {
            type: Boolean,
            default: false,
        },
        // 需要合计的列（某些列为数字却不需要计算 因此按需配置）
        summaryColumn: Array,
        // 加载列表的数据字段名  例：res.data.user.roleList  默认为 res.data
        dataName: String,
        // 同上
        totalName: String,
        // 是否开启列表单选（默认为可多选）
        single: {
            type: Boolean,
            default: false,
        },
        pagination: {
            type: Boolean,
            default: true,
        },
        spanMethod: Function,
        renderHeader: Function,
        sort: {
            default:()=>{
                return {
                    orderByColumn: "createTime",
                    isAsc: "DESC",
                }
            }
        },
    },
    data: () => {
        return {
            table: {
                data: [],
                loading: false,
                page: {
                    pageNum: 1,
                    pageSize: 10,
                },
                total: 0,
                search: {},
            },
            checkBox: {
                checkAll: false,
                checkedCities: [],
                cities: [],
                isIndeterminate: true,
            },
            renderDone: false,
        };
    },
    created() {
        let { query } = this.$route;
        // 获取列表数据
        this.getData(query);
    },
    mounted(){
        
        
        // let dom  = this.$refs.Table.$el.querySelector('.el-table__body-wrapper');
        // dom.onscroll = ()=>{
        //     console.log(
        //         dom.offsetHeight,
        //         dom.scrollTop,
        //         dom.scrollHeight
        //     )
        // }

    },
    watch: {
        submit(v) {
            this.table.loading = v;
        },
        list(v) {
            this.table.data = v || [];
        },
        "table.search"(v) {
            this.table.page.pageNum = 1;
        },
    },
    methods: {
        getData(searchParams = {}) {
            // 此处searchParams是通过FilterForm传过来的搜索参数
            delete searchParams.page;
            delete searchParams.limit;
            this.table.search = searchParams;

            let { params, list, dataName, totalName,sort } = this;
            let { page, loading, search } = this.table;

            // 存在list说明是一个静态数据表格或者一个表格表单
            if (list) {
                this.table.data = list;
                this.renderDone = true;
                return false;
            }

            // 不存在api或者加载中不继续往下走
            if (!this.api || loading) {
                this.renderDone = true;
                return false;
            }

            this.table.loading = true;
            if (params && params.page === "none") {
                this.table.page = page = {};
            }


            // 排序传值
           params =  Object.assign(params||{},sort||{});

            setTimeout(() => {
                this.api({
                    ...page,
                    ...params,
                    ...search,
                })
                    .then((res) => {
                        // 给出一个渲染前操作数据的机会
                        this.$emit("beforeRender", res);

                        let { rows, total, data } = res;
                        this.renderDone = true;
                        setTimeout(() => {
                            let d = rows || data || [];

                            if (dataName) {
                                d = this.traverseDataByName(dataName, res);
                            }

                            if (totalName) {
                                total = this.traverseDataByName(totalName, res);
                            }

                            this.table.data = d;
                            this.table.total = total || 0;
                            this.table.loading = false;
                        }, 500);
                    })
                    .catch(() => {
                        this.table.loading = false;
                        this.renderDone = true;
                    });
            }, 0);
        },
        // 遍历所需数据
        traverseDataByName(name, data) {
            let arr = name.split(".");
            let d = arr.reduce((v, next) => {
                return v[next];
            }, data);
            return d;
        },
        selectionChange(d) {
            this.$emit("select", d);
        },
        handleCheckAllChange() {},
        dblclick(row) {
            // if(timer){
            // window.clearTimeout(timer)
            this.$emit("dbClick", row);
            // }
        },
        handleRowClick(row) {
            let { selection, single } = this;
            let { Table } = this.$refs;
            this.$emit("rowClick", row);
            if (selection) {
                single && Table.clearSelection();
                Table.toggleRowSelection(row);
            }
        },
        summaryMethod(param) {
            // 自定义计算方法
            if (this._events.summary) {
                return this._events.summary[0](param);
            }

            // 默认计算方法
            const sums = [];
            const { columns, data } = param;
            let { summaryColumn } = this;

            columns.forEach((column, index) => {
                let k = column.property;

                if (index === 0) {
                    sums[index] = "合计";
                    return;
                }
                sums[index] = 0;
                data.map((v, i) => {
                    let d = v[k];
                    if (summaryColumn) {
                        summaryColumn.includes(k)
                            ? (sums[index] += Number(d))
                            : (sums[index] = "");
                    } else {
                        Number(d)
                            ? (sums[index] += Number(d))
                            : (sums[index] = "");
                    }
                });
            });

            return sums;
        },
        get() {
            return this.table.data;
        },
        cellHoverIn(row, column, cell) {
            if (!cell.getAttribute("title")) {
                let d = row[column.property];
                d && cell.setAttribute("title", d);
            }
        },
        loading(loading) {
            this.table.loading = loading;
        },
        doLayout() {
            this.$refs.Table.doLayout();
        },
    },
};
</script>

<style lang="scss" scoped>
::v-deep.table-com {
  .el-table {
    font-size: 12px;
    border: 1px solid #eaeaea;
    // .el-table__header-wrapper {
    //     border: 1px solid #eaeaea;
    //     border-bottom: none;
    // }
    // .el-table__body-wrapper {
    //     border: 1px solid #eaeaea;
    //     border-top: none;
    // }

    .el-table__empty-block {
      width: 100% !important;
    }
    th {
      & > .cell {
        text-align: center;
      }
    }
    td {
      position: relative;
      .cell {
        padding: 2px;
        text-align: center;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 1;
        overflow: hidden;
        cursor: pointer;
      }
    }

    .el-table__fixed,
    .el-table__fixed-right {
      height: calc(100% - var(--scrollXWidth) - 1px) !important;
      &::before {
        display: none;
      }
    }
    td {
      padding: 3px 5px;
      line-height: 20px;
      height: 20px;
      & + td {
        border-left: 1px solid #eaeaea;
      }
    }
  }

  &.summary {
    .el-table {
      .el-table__fixed,
      .el-table__fixed-right {
        height: calc(100% - var(--scrollXWidth) + 7px) !important;
        &::before {
          display: none;
        }
      }
    }
  }
}
</style>